package com.dubbo.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import static com.google.common.base.Preconditions.checkNotNull;

public final class DateUtils {
    public static final SimpleDateFormat SDF_YYYYMM = new SimpleDateFormat("yyyyMM");
    public static final SimpleDateFormat SDF_YYYYMMDD = new SimpleDateFormat("yyyyMMdd");
    public static final SimpleDateFormat SDF_YYYYMMDDHHMMSS = new SimpleDateFormat("yyyyMMddHHmmss");
    public static final SimpleDateFormat SDF_YYYYMMDDHHMMSSMS =
            new SimpleDateFormat("yyyyMMddHHmmssSSS");
    public static final SimpleDateFormat SDF_STANDARDIZED =
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static final int JAVA_TYPE_STRING = 1;
    public static final int JAVA_TYPE_INT = 2;
    public static final int JAVA_TYPE_LONG = 3;

    private DateUtils() {
    }

    public static int current(int field) {
        Calendar now = Calendar.getInstance();
        if (field == Calendar.MONDAY) {
            return now.get(field) + 1;
        } else {
            return now.get(field);
        }
    }

    public static Integer getAfterSixMonthDay(String type) {
        SimpleDateFormat matter = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        if ("month".equals(type)) {
            calendar.add(Calendar.MONTH, -6);
        } else {
            calendar.add(Calendar.DATE, -7);
        }
        return Integer.valueOf(matter.format(calendar.getTime()));
    }

    /**
     * @param dateType 操作时间类型是月还是天
     * @param number   距离当前时间的天数，如果是前传的是负数，之后是正数
     * @return
     */
    public static Integer calculateDate(String dateType, int number) {
        SimpleDateFormat matter = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        if ("month".equals(dateType)) {
            calendar.add(Calendar.MONTH, number);
        }
        if ("date".equals(dateType)) {
            calendar.add(Calendar.DATE, number);
        }
        return Integer.valueOf(matter.format(calendar.getTime()));
    }

    public static int getDatePeriodKey() {
        Date now = new Date();
        return Integer.parseInt(SDF_YYYYMMDD.format(now));
    }

    @SuppressWarnings("unchecked")
    public static <T> T current(SimpleDateFormat format, int javaType) {
        String s = format.format(new Date());

        if (javaType == JAVA_TYPE_STRING) {
            return (T) s;
        }

        if (javaType == JAVA_TYPE_INT) {
            return (T) Integer.valueOf(s);
        }

        if (javaType == JAVA_TYPE_LONG) {
            return (T) Long.valueOf(s);
        }

        throw new IllegalArgumentException("invalid javaType params");
    }

    @SuppressWarnings("unchecked")
    public static <T> T format(Date date, SimpleDateFormat format, int javaType) {
        String s = format.format(date);

        if (javaType == JAVA_TYPE_STRING) {
            return (T) s;
        }

        if (javaType == JAVA_TYPE_INT) {
            return (T) Integer.valueOf(s);
        }

        if (javaType == JAVA_TYPE_LONG) {
            return (T) Long.valueOf(s);
        }

        throw new IllegalArgumentException("invalid javaType params");
    }

    public static Date parse(String dateStr, SimpleDateFormat format) {
        checkNotNull(dateStr);
        try {
            return format.parse(dateStr);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    public static int diff(Date date1, Date date2, int field) {
        Calendar c1 = getCalendar(date1);
        Calendar c2 = getCalendar(date2);
        return c1.get(field) - c2.get(field);
    }

    public static Date add(Date date, int field, int amount) {
        Calendar c = getCalendar(date);
        c.add(field, amount);
        return c.getTime();
    }

    private static Calendar getCalendar(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c;
    }
}
